package behavioralPatterns.visitor;

interface Visitor {
    public void visit(ConcreteElementA element);

    public void visit(ConcreteElementB element);
}

class ConcreteVisitorA implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("ConcreteVisitorA visit ConcreteElementA");
    }

    public void visit(ConcreteElementB element) {
        System.out.println("ConcreteVisitorA visit ConcreteElementB");
    }
}

class ConcreteVisitorB implements Visitor {
    public void visit(ConcreteElementA element) {
        System.out.println("ConcreteVisitorB visit ConcreteElementA");
    }

    public void visit(ConcreteElementB element) {
        System.out.println("ConcreteVisitorB visit ConcreteElementB");
    }
}

interface Element {
    public void accept(Visitor visitor);
}

class ConcreteElementA implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

class ConcreteElementB implements Element {
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

public class VisitorPattern {
    public static void main(String[] args) {
        Visitor visitorA = new ConcreteVisitorA();
        Visitor visitorB = new ConcreteVisitorB();
        Element elementA = new ConcreteElementA();
        Element elementB = new ConcreteElementB();
        elementA.accept(visitorA);
        elementA.accept(visitorB);
        elementB.accept(visitorA);
        elementB.accept(visitorB);
    }
}

